<?php
namespace common\models;

use Yii;
use yii\base\Model;
use yii\web\UploadedFile;
use common\component\tool\Tool;


class Album extends \yii\db\ActiveRecord
{
    public static function getDb()
    {
        return Yii::$app->get("common_db");
    }
    
	public static function tableName()
    {
        return '{{%album}}';
    }

	public function rules()
    {
        return [
            ['cat_id', 'default', 'value' => 0],
            ['cat_id', 'integer', 'message' => 'cat_id必须为数字，或数字字符串', 
                       'min'=>0, 'tooSmall' => 'cat_id最小存储0', 
                       'max'=>4294967295, 'tooBig' => 'cat_id最大存储4294967295'],
            ['album_name', 'required', 'message' => 'album_name不能为空', 'on' => 'add'],
            ['album_name', 'string', 'message' => 'album_name必须是字符串',
                           'max' => 64, 'tooLong' => 'album_name最长64位'],
            ['album_path', 'required', 'message' => 'album_path不能为空', 'on' => 'add'],
            ['album_path', 'string', 'message' => 'album_path必须是字符串',
                           'max' => 256, 'tooLong' => 'album_path最长256位'],
            ['album_size', 'default', 'value' => 0],
            ['album_size', 'integer', 'message' => 'album_size必须为数字，或数字字符串', 
                            'min'=>0, 'tooSmall' => 'album_size最小存储0', 
                            'max'=>4294967295, 'tooBig' => 'album_size最大存储4294967295'],
            ['album_md5', 'required', 'message' => 'album_md5不能为空', 'on' => 'add'],
            ['album_md5', 'unique', 'message' => 'album_md5已经存在',],
            ['album_md5', 'string', 'message' => 'album_md5必须是字符串',
                           'max' => 256, 'tooLong' => 'album_md5最长256位'],
            // ['diff_size', 'default', 'value' => 1],
            ['diff_size', 'integer', 'message' => 'diff_size必须为数字，或数字字符串'],
            ['diff_size', 'in', 'range' => array(0, 1, 2, 3, 4), 'message' => 'diff_size值必须在0~4中选择'],              
            ['is_cover', 'default', 'value' => 1],
            ['is_cover', 'integer', 'message' => 'is_cover必须为数字，或数字字符串'],
            ['is_cover', 'in', 'range' => array(1, 2), 'message' => 'is_cover值必须在1,2中选择'],
            ['sort', 'integer', 'message' => 'sort必须为数字，或数字字符串', 
                     'min'=>0, 'tooSmall' => 'sort最小存储0', 
                     'max'=>4294967295, 'tooBig' => 'sort最大存储4294967295'],
            ['add_time', 'default', 'value' => '1000-01-01 00:00:00'],
            ['add_time', 'date', 'format'=>'yyyy-MM-dd HH:mm:ss', 'message' => 'add_time非yyyy-MM-dd HH:mm:ss格式'],
            ['app_id', 'default', 'value' => 0],
            ['app_id', 'integer', 'message' => 'app_id必须为数字，或数字字符串', 
                        'min'=>0, 'tooSmall' => 'app_id最小存储0', 
                        'max'=>4294967295, 'tooBig' => 'app_id最大存储4294967295'],
            ['com_id', 'default', 'value' => 0],
            ['com_id', 'integer', 'message' => 'com_id必须为数字，或数字字符串', 
                        'min'=>0, 'tooSmall' => 'com_id最小存储0', 
                        'max'=>4294967295, 'tooBig' => 'com_id最大存储4294967295'],
        ];
    }


    /*
    上传图片
    $post       上次附带的数据
    $uploadFileName      文件夹名称（如果是认证中心则是comid，如果是实例则是appid）
    $com_id     传到那个企业ID下(对内)
    $app_id     实例(对内)
    */
    public function upload($post, $uploadFileName, $com_id = 0, $app_id = 0)
    {
        /*上传过来的图片，放到指定的位置*/
        $UploadForm = new UploadForm();
        $UploadForm->file = UploadedFile::getInstance($UploadForm, 'file');
        // P($UploadForm->file);
        if ($UploadForm->file && $UploadForm->validate()) {
            // $fileName = $UploadForm->file->baseName . '.' . $UploadForm->file->extension;
            $fileName = date("Ymd").Tool::generateRandomStr(3).date("His").Tool::generateRandomStr(3);//文件名称
            $fileSuffix = '.' . $UploadForm->file->extension;//文件后缀
            /*判断图片类型是否在允许的范围内，主要判断type*/
            if(($fileSuffix2 = $this->inAllowType($UploadForm->file->type)) === false){
                P('此类型不允许上传');
            }
            if($fileSuffix == '.'){
                $fileSuffix = $fileSuffix2;
                // P($fileSuffix);
            }
            $folderName = date('Ymd');//放进今天日期的文件夹中
            $path = Yii::$app->basePath . '/web/' . Yii::$app->params['uploadPath'] . $uploadFileName . '/images/origin/' . $folderName;//存放的路径(原始文件)（不包含文件名）
            if(!file_exists($path)){//创建今天日期的文件夹
                mkdir($path, 0777, true);
                chmod($path, 0777);
            }
            $size = Yii::$app->params['imgSize'];//得到图片的几种尺寸
            $otherPath = [];//其他裁剪图片的路径
            foreach($size as $k => $v){
                array_push($otherPath, Yii::$app->basePath . '/web/' . Yii::$app->params['uploadPath'] . $uploadFileName . '/images/'. $v .'/' . $folderName);//存放的路径（不包含文件名）
            }
            foreach($otherPath as $k => $v){
                if(!file_exists($v)){//创建今天日期的文件夹
                    mkdir($v, 0777, true);
                    chmod($v, 0777);
                }
            }
            if($UploadForm->file->saveAs($path . '/' . $fileName . $fileSuffix)){
                $albumPath = Yii::$app->params['uploadPath'] . $uploadFileName . '/images/origin/' . $folderName . '/' . $fileName . $fileSuffix;//上传成功的图片路径
                // P($albumPath);
                /*判断是否在规定的*/
                $imgInfo = getimagesize($albumPath);
                // P($imgInfo);
                if(!isset($imgInfo['mime']) or !$this->inAllowType($imgInfo['mime'])){
                    unlink($albumPath);
                    P('此类型不允许上传');
                }

                /*判断此文件是否已经存在，如果存在则删除上传的文件*/
                $albumMd5 = md5_file($albumPath);
                if(!is_null($album = self::find()->where('album_md5 ="' . $albumMd5 . '"')->one())){
                    unlink($albumPath);
                    $info = array(
                        'name' => $album->album_name,
                        'diffsize' => $album->diff_size,
                        'url' => Tool::getAlbumBySizenum($album->album_path, $album->diff_size),
                    );
                    // P($info);
                    return $info;
                }
                /*插入到相册表中albumId*/
                $originFileName = mb_substr($UploadForm->file->name, 0, 64, 'utf-8');
                $data = array(
                    'Album' => array(
                        'cat_id' => $post['catId'],
                        'album_name' => $originFileName,//截取前64个字符 因为数据库只够放64位
                        'album_path' => '/' . $albumPath,
                        'album_size' => filesize($albumPath),//获取大小
                        'album_md5' => $albumMd5,
                        'add_time' => date('Y-m-d H:i:s', time()),
                        'app_id' => $app_id,
                        'com_id' => $com_id
                    )
                );
                if($this->load($data) and $this->validate()){
                    /*保存到相册*/
                    if($this->save(false)){
                        $id = $this->getPrimaryKey();
                        $this->updateAll(['sort' => $id], 'album_id = :id', [':id' => $id]);//排序和id一样
                        /*更新所属相册的 数量、大小*/
                        $imgSize = filesize($path . '/' . $fileName . $fileSuffix);//获取图片大小
                        AlbumCategory::updateAllCounters(['album_number' => 1, 'album_size' => $imgSize], 'cat_id = :cat_id', [':cat_id' => $post['catId']]);
                        /*复制 并 处理 其他几种尺寸的图片>>>>>>*/
                        $imgInfo = getimagesize($path . '/' . $fileName . $fileSuffix);//获取图片信息
                        $imgWidth = $imgInfo[0];//图片的宽度
                        $imgHeight = $imgInfo[1];//图片的高度
                        $num = 0;//记录裁剪出了几张图片 默认0张
                        foreach($size as $k => $v){
                            if($imgWidth > $v or $imgHeight > $v){
                                $num++;
                            }
                        }
                        $index = 0;
                        foreach($size as $k => $v){
                            if($imgWidth > $v or $imgHeight > $v){
                                $this->image_resize($path . '/' . $fileName . $fileSuffix, $otherPath[$index++] . '/' . $fileName . '!!' . $num . '_' . $v . 'x' . $v . $fileSuffix, $v, $v);
                            }
                        }
                        // if($num >= count($size)){//如果每个尺寸都裁剪了，说明此图特别大，需删除原图
                        //     unlink($path . '/' . $fileName . $fileSuffix);//删除原图
                        // }
                        /*复制 并 处理 其他几种尺寸的图片<<<<<<*/

                        if($num > 0){
                            /*更新 不同的尺寸数量*/
                            self::updateAll(['diff_size' => $num], 'album_md5 = :md5', [':md5' => $albumMd5]);
                            if($num > 2){//说明有图片需要2次裁剪，返回的是300*300的图片，否则返回原图
                                $info = array(
                                    'name' => $originFileName,
                                    'diffsize' => $num,
                                    'url' => '/' . Yii::$app->params['uploadPath'] . $uploadFileName . '/images/' . $size['big_img'] . '/' . $folderName . '/' . $fileName . '!!' . $num . '_' . $size['big_img'] . 'x' . $size['big_img'] . $fileSuffix
                                );
                                return $info;
                            }
                        }
                        $info = array(
                            'name' => $originFileName,
                            'diffsize' => $num,
                            'url' => '/' . Yii::$app->params['uploadPath'] . $uploadFileName . '/images/origin/' . $folderName . '/' . $fileName . $fileSuffix
                        );
                        return $info;
                    }else{
                        P('上传失败');
                    }
            	}
                
            }

            return false;

        }

    }

    /*判断是否是允许上传的图片类型, 如果有的话，返回后缀名*/
    private function inAllowType($type)
    {
        foreach(Yii::$app->params['allowImageType'] as $k => $v){
            if($k == $type){
                return $v;
            }
        }
        return false;
    }


    /*
    把大图缩略到缩略图指定的范围内,可能有留白（原图细节不丢失，不失真）
    $f      原始图片（包含路径）
    $t      裁剪之后的图片（包含路径）
    $tw     图片的宽度
    $th     图片的高度
    */
    private function image_resize($f, $t, $tw, $th)
    {
    // 按指定大小生成缩略图，而且不变形，缩略图函数
        $temp = array(1=>'gif', 2=>'jpeg', 3=>'png');

        list($fw, $fh, $tmp) = getimagesize($f);

        if(!$temp[$tmp]){
            return false;
        }
        $tmp = $temp[$tmp];
        $infunc = "imagecreatefrom$tmp";
        $outfunc = "image$tmp";

        $fimg = $infunc($f);

        // 使缩略后的图片不变形，并且限制在 缩略图宽高范围内
        if($fw/$tw > $fh/$th){
            $th = $tw*($fh/$fw);
        }else{
            $tw = $th*($fw/$fh);
        }

        $timg = imagecreatetruecolor($tw, $th);

        /*设置背景透明，正对PNG格式的图片，否则背景会变成黑色*/
        imagealphablending($timg, true);
        imagesavealpha($timg, true);
        $trans_colour = imagecolorallocatealpha($timg, 0, 0, 0, 127);
        imagefill($timg, 0, 0, $trans_colour);

        imagecopyresampled($timg, $fimg, 0,0, 0,0, $tw,$th, $fw,$fh);
        if($outfunc($timg, $t)){
            return true;
        }else{
            return false;
        }
    }

    /*失真缩放*/
    private function img_create_small($big_img, $width, $height, $small_img)
    {//原始大图地址，缩略图宽度，高度，缩略图地址
        $imgage = getimagesize($big_img); //得到原始大图片
        switch ($imgage[2]) { // 图像类型判断
            case 1:
                $im = imagecreatefromgif($big_img);
                break;
            case 2:
                $im = imagecreatefromjpeg($big_img);
                break;
            case 3:
                $im = imagecreatefrompng($big_img);
                break;
        }
        $src_W = $imgage[0]; //获取大图片宽度
        $src_H = $imgage[1]; //获取大图片高度
        $tn = imagecreatetruecolor($width, $height); //创建缩略图
        imagecopyresampled($tn, $im, 0, 0, 0, 0, $width, $height, $src_W, $src_H); //复制图像并改变大小
        imagejpeg($tn, $small_img); //输出图像
    }

}
?>